package com.example.ds.utils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.ds.base.BaseEntity;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author 姚勇
 */
public class WrapperUtil {

    /**
     * 注意实体类字段命名规范
     */
    public static final String PRIMARY_KEY = "id";
    public static final String FOREIGN_KEY = "Id";
    /**
     * 时间范围查询开始字段
     */
    public static final String CREATED = "created";
    public static final String UPDATED = "updated";
    /**
     * 时间范围查询结束字段
     */
    public static final String CREATED_END = "created_end";
    public static final String UPDATED_END = "updated_end";

    /**
     * 初始化一个查询构造器
     *
     * @param t
     * @param <T>
     * @return
     */
    public static <T extends BaseEntity> QueryWrapper<T> initQueryWrapper(T t, HttpServletRequest request) {
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        try {
            if (t != null) {
                //拿到所有字段
                List<Field> fields = getFields(t);
                for (Field field : fields) {
                    field.setAccessible(true);
                    if (PRIMARY_KEY.equals(field.getName()) || field.getName().endsWith(FOREIGN_KEY)) {
                        //如果查询条件是id,默认精确查询
                        wrapper.eq(Objects.nonNull(field.get(t)), field.getName(), field.get(t));
                    } else if ("java.lang.String".equals(field.getType().getName())) {
                        //如果是字符串,默认模糊查询
                        wrapper.like(Objects.nonNull(field.get(t)), field.getName(), field.get(t));
                    } else if ("java.time.LocalDateTime".equals(field.getType().getName())) {
                        //如果是日期时间,默认大于等于当前时间
                        wrapper.ge(Objects.nonNull(field.get(t)), field.getName(), field.get(t));
                    } else {
                        //其他类型,默认精确查询
                        wrapper.eq(Objects.nonNull(field.get(t)), field.getName(), field.get(t));
                    }
                    field.setAccessible(false);
                }
            }

            //如果Request对象中含有特殊字段,比如日期区间的第二个字段created_end/updated_end等
            wrapper.le(Objects.nonNull(request.getParameter(CREATED_END)), CREATED, request.getParameter(CREATED_END));
            wrapper.le(Objects.nonNull(request.getParameter(UPDATED_END)), UPDATED, request.getParameter(UPDATED_END));

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return wrapper;
    }

    /**
     * 初始化一个更新构造器
     *
     * @param <T>
     * @param t
     * @return
     */
    public static <T extends BaseEntity> UpdateWrapper<T> initUpdateWrapper(T t) {
        UpdateWrapper<T> wrapper = new UpdateWrapper<>();
        if (t != null) {
            wrapper.eq(Objects.nonNull(t.getId()), PRIMARY_KEY, t.getId());
        }
        return wrapper;
    }

    /**
     * 拿到类的所有字段,包括父类字段
     *
     * @param object
     * @return
     */
    private static List<Field> getFields(Object object) {
        List<Field> fieldList = new ArrayList<>();
        Class<?> clazz = object.getClass();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        return fieldList;
    }
}
